How can I use the zip method in my Jinja2 template?

by: erikvm, 8 years ago

Last edited: 8 years ago

Hi Harrison, thanks for existing, your tutorials are of tremendous help. I have run into a problem that I can't find a solution to. What I'm trying to do is parse some data from a website and display these values on my local flask app. Here's my code


from bs4 import BeautifulSoup
from flask import Flask, render_template, jsonify, request
import requests

@app.route("/")
def index():
    tvPage = requests.get("https://www.freeview.co.uk")
    tvSoup = BeautifulSoup(tvPage.content)
    tvData = tvSoup.find_all("dt")
    tvData2 = tvSoup.find_all("dd")
    tvList = []
    for x, y in zip(tvData,tvData2):
        tvList = tvList + [x,y]
    tvNews = tvList[:28]

return render_template("main.html",tvNews=tvNews)

if __name__ == '__main__':
app.run(debug=True,port=5200)



And in my "main.html" the loop looks like this:


{% for program in tvNews %}
{{ program.text }}
{% endfor %}


What I'm trying to achieve is have the code be displayed like this: http://imgur.com/a/EfE5Q - so timeslot followed by program title, and not like this: http://imgur.com/a/EMzK3

So how can I somehow use the zip method (or whatever is necessary) to have the desired outcome?

Thanks in advance

I realized that I could add another for loop in my Python code that goes


a = 0
for i in tvNews:
   print (tvNews[a],tvNews[a+1]
   a = a + 1

But I'm not sure how to translate this into Flask..




You must be logged in to post. Please login or register an account.



Interestingly enough,

I tried to add some changes


        tvPage = requests.get("https://www.freeview.co.uk")
tvSoup = BeautifulSoup(tvPage.content)
tvData = tvSoup.find_all("dt")
tvData2 = tvSoup.find_all("dd")
tvList = []
for x, y in zip(tvData,tvData2):
tvList = tvList + [x,y]


tvList2 = []
tvLoop = [" ".join(str(line)) for line in zip(tvData, tvData2)]
for i in tvLoop:
tvList2 = tvList2 + [i]
tvNews = tvList2[:14]


and it works with


{% for program in tvNews %}
<ul>{{ program }}</ul>
{% endfor %}

Which gives me the element tags as well, <dt> and <dd>
But not with program.text in the HTML, then it just returns an empty string

-erikvm 8 years ago
Last edited 8 years ago

You must be logged in to post. Please login or register an account.

So, rather than doing zip in HTML/Jinja, do it in python. Zip, to a single list, then pass THAT list to HTML, iterate through that list, which will have two elements each, then you can just do [0] and [1] and you've got what you want.

As for the tags being there, use .text on the elements themselves to get JUST the text.

For example, in a line like this:
	for x, y in zip(tvData,tvData2):
tvList = tvList + [x,y]

You should be able to do something like:

	for x, y in zip(tvData,tvData2):
tvList = tvList + [x.text,y.text]


For the method I mentioned above tho, you can pass more than just strings to jinja, you can pass objects and continue to treat them as the objects they are, so you can actually just zip the stuff together to a python list, and literally pass that python list...then, in your for loop, you can iterate through the loop, referencing the elements by index and then adding the .text to them there in Jinja.

-Harrison 8 years ago
Last edited 8 years ago

You must be logged in to post. Please login or register an account.




So, rather than doing zip in HTML/Jinja, do it in python.
Zip, to a single list, then pass THAT list to HTML, iterate through that list, which will have two elements each, then you can just do [0] and [1] and you've got what you want.



I don't quite understand this. Can I use the list methods in my html? [0] and [1]?




then, in your for loop, you can iterate through the loop, referencing the elements by index and then adding the .text to them there in Jinja.


Unclear of this process - can you please explain further what you mean?

Up until now I have passed everything in python, including the zip method but it still won't return the desired outcome. I can either have everything with tags, and displayed correctly:
<tag here>(timeslot: </tag here>  <tag>program) </tag here>

or
timeslot
program

without tags.

When I tried using "program.text" in my jinja2 for loop, everything was gone (i learned that it returned a None value, for whatever reason...)



-erikvm 8 years ago
Last edited 8 years ago

You must be logged in to post. Please login or register an account.